home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-11-09 | 33.6 KB | 666 lines | [TEXT/pdos] |
- Apple II
- Technical Notes
- _____________________________________________________________________________
- Developer Technical Support
-
-
- ProDOS 8
- #17: Recursive ProDOS Catalog Routine
-
- Revised by: Dave Lyons, Keith Rollin, & Matt Deatherage November 1989
- Written by: Greg Seitz December 1983
-
- This Technical Note presents an assembly language example of a recursive
- directory reading routine which is AppleShare compatible.
- Changes since November 1988: The routine now ignores the file_count
- field in a directory, and it properly increments ThisBlock. More discussion
- of AppleShare volumes is included.
- _____________________________________________________________________________
-
- This Note presents a routine in assembly language for recursively cataloging a
- ProDOS directory. If you apply this technique to the volume directory of a
- disk, it will display the name of every file stored on the disk. The routine
- displays the contents of a given directory (the volume directory in this
- case), displays the contents of each subdirectory as it is encountered.
-
- READ_BLOCK is not used, since it does not work with AppleShare servers. READ
- is used instead, since it works for AppleShare volumes as well as local disks.
- Instead of using directory pointers to decide which block to read next, we
- simply read the directory and display filenames as we go, until we reach a
- subdirectory file. When we reach a subdirectory, the routine saves our place,
- plunges down one level of the tree structure, and catalogs the subdirectory.
- You repeat the process if you find a subdirectory at the current level. When
- you reach the EOF of any directory, the routine closes the current directory
- and pops back up one level, and when it reaches the EOF of the initial
- directory, the routine is finished.
-
- This routine is generally compatible with AppleShare volumes, but it is
- impossible to guarantee a complete traversal of all the accessible files on an
- AppleShare volume: another user on the same volume can add or remove files or
- directories at any time. If entries are added or removed, some filenames may
- be displayed twice or missed completely. Be sure that your programs deal with
- this sort of situation adequately.
-
- We assume that AppleShare is in short naming mode (as it is by default under
- ProDOS 8). If you enable long naming mode, then illegal characters in
- filenames will not be translated into question marks. In this case, the code
- would need to be modified to deal with non-ASCII characters. Also, the
- ChopName routine would need to be aware that a slash (/) character could be
- contained inside the name of a directory that had been added to the pathname.
- (As the code stands, such directories fail to open, but their names are still
- temporarily added to the pathname.)
-
- When the catalog routine encounters an error, it displays a brief message and
- continues. It is important not to abort on an error, since AppleShare volumes
- generally contain files and folders with names that are inaccessible to
- ProDOS, as well as folders that are inaccessible to your program's user (error
- $4E, access error).
-
- The code example includes a simple test of the ReadDir routine, which is the
- actual recursive catalog routine. Note that the simple test relies upon the
- GETBUFR routine in BASIC.SYSTEM to allocate a buffer; therefore, as presented,
- the routine requires the presence of BASIC.SYSTEM. The actual ReadDir routine
- requires nothing outside of the ProDOS 8 MLI.
-
- ----- NEXT OBJECT FILE NAME IS CATALOG.0
- 0800: 0800 2 org $800
- 0800: 3 *******************************************************
- 0800: 4 *
- 0800: 5 * Recursive ProDOS Catalog Routine
- 0800: 6 *
- 0800: 7 * by: Greg Seitz 12/83
- 0800: 8 * Pete McDonald 1/86
- 0800: 9 * Keith Rollin 7/88
- 0800: 10 * Dave Lyons 11/89
- 0800: 11 *
- 0800: 12 * This program shows the latest "Apple Approved"
- 0800: 13 * method for reading a directory under ProDOS 8.
- 0800: 14 * READ_BLOCK is not used, since it is incompatible
- 0800: 15 * with AppleShare file servers.
- 0800: 16 *
- 0800: 17 * November 1989: The file_count field is no longer
- 0800: 18 * used (all references to ThisEntry were removed).
- 0800: 19 * This is because the file count can change on the fly
- 0800: 20 * on AppleShare volumes. (Note that the old code was
- 0800: 21 * accidentally decrementing the file count when it
- 0800: 22 * found an entry for a deleted file, so some files
- 0800: 23 * could be left off the end of the list.)
- 0800: 24 *
- 0800: 25 * Also, ThisBlock now gets incremented when a chunk
- 0800: 26 * of data is read from a directory. Previously, this
- 0800: 27 * routine could get stuck in an endless loop when
- 0800: 28 * a subdirectory was found outside the first block of
- 0800: 29 * its parent directory.
- 0800: 30 *
- 0800: 31 * Limitations: This routine cannot reach any
- 0800: 32 * subdirectory whose pathname is longer than 64
- 0800: 33 * characters, and it will not operate correctly if
- 0800: 34 * any subdirectory is more than 255 blocks long
- 0800: 35 * (because ThisBlock is only one byte).
- 0800: 36 *
- 0800: 37 *******************************************************
- 0800: 38 *
- 0800: 39 * Equates
- 0800: 40 *
- 0800: 41 * Zero page locations
- 0800: 42 *
- 0800: 0080 43 dirName equ $80 ; pointer to directory name
- 0800: 0082 44 entPtr equ $82 ; ptr to current entry
- 0800: 45 *
- 0800: 46 * ProDOS command numbers
- 0800: 47 *
- 0800: BF00 48 MLI equ $BF00 ; MLI entry point
- 0800: 00C7 49 mliGetPfx equ $C7 ; GET_PREFIX
- 0800: 00C8 50 mliOpen equ $C8 ; Open a file command
- 0800: 00CA 51 mliRead equ $CA ; Read a file command
- 0800: 00CC 52 mliClose equ $CC ; Close a file command
- 0800: 00CE 53 mliSetMark equ $CE ; SET_MARK command
- 0800: 004C 54 EndOfFile equ $4C ; EndOfFile error
- 0800: 55 *
- 0800: 56 * BASIC.SYSTEM stuff
- 0800: 57 *
- 0800: BEF5 58 GetBufr equ $BEF5 ; BASIC.SYSTEM get buffer routine
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 3
-
- 0800: 59 *
- 0800: 60 * Offsets into the directory
- 0800: 61 *
- 0800: 0000 62 oType equ $0 ; offset to file type byte
- 0800: 0023 63 oEntLen equ $23 ; length of each dir. entry
- 0800: 0024 64 oEntBlk equ $24 ; entries in each block
- 0800: 65 *
- 0800: 66 * Monitor routines
- 0800: 67 *
- 0800: FDED 68 cout equ $FDED ; output a character
- 0800: FD8E 69 crout equ $FD8E ; output a RETURN
- 0800: FDDA 70 prbyte equ $FDDA ; print byte in hex
- 0800: 00A0 71 space equ $A0 ; a space character
- 0800: 72 *
- 0800: 73 *******************************************************
- 0800: 74 *
- 0800: 0800 75 Start equ *
- 0800: 76 *
- 0800: 77 * Simple routine to test the recursive ReadDir
- 0800: 78 * routine. It gets an I/O buffer for ReadDir, gets
- 0800: 79 * the current prefix, sets the depth of recursion
- 0800: 80 * to zero, and calls ReadDir to process all of the
- 0800: 81 * entries in the directory.
- 0800: 82 *
- 0800:A9 04 83 lda #4 ; get an I/O buffer
- 0802:20 F5 BE 84 jsr GetBufr
- 0805:B0 17 081E 85 bcs exit ; didn't get it
- 0807:8D D7 09 86 sta ioBuf+1
- 080A: 87 *
- 080A: 88 * Use the current prefix for the name of the
- 080A: 89 * directory to display. Note that the string we
- 080A: 90 * pass to ReadDir has to end with a "/", and that
- 080A: 91 * the result of GET_PREFIX does.
- 080A: 92 *
- 080A:20 00 BF 93 jsr MLI
- 080D:C7 94 db mliGetPfx
- 080E:E8 09 95 dw GetPParms
- 0810:B0 0C 081E 96 bcs exit
- 0812: 97 *
- 0812:A9 00 98 lda #0
- 0814:8D CE 09 99 sta Depth
- 0817: 100 *
- 0817:A9 EB 101 lda #nameBuffer
- 0819:A2 0B 102 ldx #<nameBuffer
- 081B:20 1F 08 103 jsr ReadDir
- 081E: 104 *
- 081E: 081E 105 exit equ *
- 081E:60 106 rts
- 081F: 107 *
- 081F: 108 *******************************************************
- 081F: 109 *******************************************************
- 081F: 110 *
- 081F: 081F 111 ReadDir equ *
- 081F: 112 *
- 081F: 113 * This is the actual recursive routine. It takes as
- 081F: 114 * input a pointer to the directory name to read in
- 081F: 115 * A,X (lo,hi), opens it, and starts to read the
- 081F: 116 * entries. When it encounters a filename, it calls
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 4
-
- 081F: 117 * the routine "VisitFile". When it encounters a
- 081F: 118 * directory name, it calls "VisitDir".
- 081F: 119 *
- 081F: 120 * The directory pathname string must end with a "/"
- 081F: 121 * character.
- 081F: 122 *
- 081F: 123 *******************************************************
- 081F: 124 *
- 081F:85 80 125 sta dirName ; save a pointer to name
- 0821:86 81 126 stx dirName+1
- 0823: 127 *
- 0823:8D D4 09 128 sta openName ; set up OpenFile params
- 0826:8E D5 09 129 stx openName+1
- 0829: 130 *
- 0829: 0829 131 ReadDir1 equ * ; recursive entry point
- 0829:20 79 08 132 jsr OpenDir ; open the directory as a file
- 082C:B0 1F 084D 133 bcs done
- 082E: 134 *
- 082E:4C 48 08 135 jmp nextEntry ; jump to the end of the loop
- 0831: 136 *
- 0831: 0831 137 loop equ *
- 0831:A0 00 138 ldy #oType ; get type of current entry
- 0833:B1 82 139 lda (entPtr),y
- 0835:29 F0 140 and #$F0 ; look at 4 high bits
- 0837:C9 00 141 cmp #0 ; inactive entry?
- 0839:F0 0D 0848 142 beq nextEntry ; yes - bump to next one
- 083B:C9 D0 143 cmp #$D0 ; is it a directory?
- 083D:F0 06 0845 144 beq ItsADir ; yes, so call VisitDir
- 083F:20 B3 08 145 jsr VisitFile ; no, it's a file
- 0842:4C 48 08 146 jmp nextEntry
- 0845: 147 *
- 0845:20 BA 08 148 ItsADir jsr VisitDir
- 0848: 0848 149 nextEntry equ *
- 0848:20 77 09 150 jsr GetNext ; get pointer to next entry
- 084B:90 E4 0831 151 bcc loop ; Carry set means we're done
- 084D: 084D 152 done equ * ; moved before PHA (11/89 DAL)
- 084D:48 153 pha ; save error code
- 084E: 154 *
- 084E:20 00 BF 155 jsr MLI ; close the directory
- 0851:CC 156 db mliClose
- 0852:E1 09 157 dw CloseParms
- 0854: 158 *
- 0854:68 159 pla ;we're expecting EndOfFile error
- 0855:C9 4C 160 cmp #EndOfFile
- 0857:F0 1F 0878 161 beq hitDirEnd
- 0859: 162 *
- 0859: 163 * We got an error other than EndOfFile--report the
- 0859: 164 * error clumsily ("ERR=$xx").
- 0859: 165 *
- 0859:48 166 pha
- 085A:A9 C5 167 lda #'E'|$80
- 085C:20 ED FD 168 jsr cout
- 085F:A9 D2 169 lda #'R'|$80
- 0861:20 ED FD 170 jsr cout
- 0864:20 ED FD 171 jsr cout
- 0867:A9 BD 172 lda #'='|$80
- 0869:20 ED FD 173 jsr cout
- 086C:A9 A4 174 lda #'$'|$80
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 5
-
- 086E:20 ED FD 175 jsr cout
- 0871:68 176 pla
- 0872:20 DA FD 177 jsr prbyte
- 0875:20 8E FD 178 jsr crout
- 0878: 179 *
- 0878: 0878 180 hitDirEnd equ *
- 0878:60 181 rts
- 0879: 182 *
- 0879: 183 *******************************************************
- 0879: 184 *
- 0879: 0879 185 OpenDir equ *
- 0879: 186 *
- 0879: 187 * Opens the directory pointed to by OpenParms
- 0879: 188 * parameter block. This pointer should be init-
- 0879: 189 * ialized BEFORE this routine is called. If the
- 0879: 190 * file is successfully opened, the following
- 0879: 191 * variables are set:
- 0879: 192 *
- 0879: 193 * xRefNum ; all the refnums
- 0879: 194 * entryLen ; size of directory entries
- 0879: 195 * entPtr ; pointer to current entry
- 0879: 196 * ThisBEntry ; entry number within this block
- 0879: 197 * ThisBlock ; offset (in blocks) into dir.
- 0879: 198 *
- 0879:20 00 BF 199 jsr MLI ; open dir as a file
- 087C:C8 200 db mliOpen
- 087D:D3 09 201 dw OpenParms
- 087F:B0 31 08B2 202 bcs OpenDone
- 0881: 203 *
- 0881:AD D8 09 204 lda oRefNum ; copy the refnum return-
- 0884:8D DA 09 205 sta rRefNum ; ed by Open into the
- 0887:8D E2 09 206 sta cRefNum ; other param blocks.
- 088A:8D E4 09 207 sta sRefNum
- 088D: 208 *
- 088D:20 00 BF 209 jsr MLI ; read the first block
- 0890:CA 210 db mliRead
- 0891:D9 09 211 dw ReadParms
- 0893:B0 1D 08B2 212 bcs OpenDone
- 0895: 213 *
- 0895:AD 0E 0A 214 lda buffer+oEntLen ; init 'entryLen'
- 0898:8D D1 09 215 sta entryLen
- 089B: 216 *
- 089B:A9 EF 217 lda #buffer+4 ; init ptr to first entry
- 089D:85 82 218 sta entPtr
- 089F:A9 09 219 lda #<buffer+4
- 08A1:85 83 220 sta entPtr+1
- 08A3: 221 *
- 08A3:AD 0F 0A 222 lda buffer+oEntblk ; init these values based on
- 08A6:8D CF 09 223 sta ThisBEntry ; values in the dir header
- 08A9:8D D2 09 224 sta entPerBlk
- 08AC: 225 *
- 08AC:A9 00 226 lda #0 ; init block offset into dir.
- 08AE:8D D0 09 227 sta ThisBlock
- 08B1: 228 *
- 08B1:18 229 clc ; say that open was OK
- 08B2: 230 *
- 08B2: 08B2 231 OpenDone equ *
- 08B2:60 232 rts
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 6
-
- 08B3: 233 *
- 08B3: 234 *******************************************************
- 08B3: 235 *
- 08B3: 08B3 236 VisitFile equ *
- 08B3: 237 *
- 08B3: 238 * Do whatever is necessary when we encounter a
- 08B3: 239 * file entry in the directory. In this case, we
- 08B3: 240 * print the name of the file.
- 08B3: 241 *
- 08B3:20 AC 09 242 jsr PrintEntry
- 08B6:20 8E FD 243 jsr crout
- 08B9:60 244 rts
- 08BA: 245 *
- 08BA: 246 *******************************************************
- 08BA: 247 *
- 08BA: 08BA 248 VisitDir equ *
- 08BA: 249 *
- 08BA: 250 * Print the name of the subdirectory we are looking
- 08BA: 251 * at, appending a "/" to it (to indicate that it's
- 08BA: 252 * a directory), and then calling RecursDir to list
- 08BA: 253 * everything in that directory.
- 08BA: 254 *
- 08BA:20 AC 09 255 jsr PrintEntry ; print dir's name
- 08BD:A9 AF 256 lda #'/'|$80 ; tack on / at end
- 08BF:20 ED FD 257 jsr cout
- 08C2:20 8E FD 258 jsr crout
- 08C5: 259 *
- 08C5:20 C9 08 260 jsr RecursDir ; enumerate all entries in sub-dir.
- 08C8: 261 *
- 08C8:60 262 rts
- 08C9: 263 *
- 08C9: 264 *******************************************************
- 08C9: 265 *
- 08C9: 08C9 266 RecursDir equ *
- 08C9: 267 *
- 08C9: 268 * This routine calls ReadDir recursively. It
- 08C9: 269 *
- 08C9: 270 * - increments the recursion depth counter,
- 08C9: 271 * - saves certain variables onto the stack
- 08C9: 272 * - closes the current directory
- 08C9: 273 * - creates the name of the new directory
- 08C9: 274 * - calls ReadDir (recursively)
- 08C9: 275 * - restores the variables from the stack
- 08C9: 276 * - restores directory name to original value
- 08C9: 277 * - re-opens the old directory
- 08C9: 278 * - moves to our last position within it
- 08C9: 279 * - decrements the recursion depth counter
- 08C9: 280 *
- 08C9:EE CE 09 281 inc Depth ; bump this for recursive call
- 08CC: 282 *
- 08CC: 283 * Save everything we can think of (the women,
- 08CC: 284 * the children, the beer, etc.).
- 08CC: 285 *
- 08CC:A5 83 286 lda entPtr+1
- 08CE:48 287 pha
- 08CF:A5 82 288 lda entPtr
- 08D1:48 289 pha
- 08D2:AD CF 09 290 lda ThisBEntry
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 7
-
- 08D5:48 291 pha
- 08D6:AD D0 09 292 lda ThisBlock
- 08D9:48 293 pha
- 08DA:AD D1 09 294 lda entryLen
- 08DD:48 295 pha
- 08DE:AD D2 09 296 lda entPerblk
- 08E1:48 297 pha
- 08E2: 298 *
- 08E2: 299 * Close the current directory, as ReadDir will
- 08E2: 300 * open files of its own, and we don't want to
- 08E2: 301 * have a bunch of open files lying around.
- 08E2: 302 *
- 08E2:20 00 BF 303 jsr MLI
- 08E5:CC 304 db mliClose
- 08E6:E1 09 305 dw CloseParms
- 08E8: 306 *
- 08E8:20 2F 09 307 jsr ExtendName ; make new dir name
- 08EB: 308 *
- 08EB:20 29 08 309 jsr ReadDir1 ; enumerate the subdirectory
- 08EE: 310 *
- 08EE:20 65 09 311 jsr ChopName ; restore old directory name
- 08F1: 312 *
- 08F1:20 79 08 313 jsr OpenDir ; re-open it back up
- 08F4:90 01 08F7 314 bcc reOpened
- 08F6: 315 *
- 08F6: 316 * Can't continue from this point--exit in
- 08F6: 317 * whatever way is appropriate for your
- 08F6: 318 * program.
- 08F6: 319 *
- 08F6:00 320 brk
- 08F7: 321 *
- 08F7: 08F7 322 reOpened equ *
- 08F7: 323 *
- 08F7: 324 * Restore everything that we saved before
- 08F7: 325 *
- 08F7:68 326 pla
- 08F8:8D D2 09 327 sta entPerBlk
- 08FB:68 328 pla
- 08FC:8D D1 09 329 sta entryLen
- 08FF:68 330 pla
- 0900:8D D0 09 331 sta ThisBlock
- 0903:68 332 pla
- 0904:8D CF 09 333 sta ThisBEntry
- 0907:68 334 pla
- 0908:85 82 335 sta entPtr
- 090A:68 336 pla
- 090B:85 83 337 sta entPtr+1
- 090D: 338 *
- 090D:A9 00 339 lda #0
- 090F:8D E5 09 340 sta Mark
- 0912:8D E7 09 341 sta Mark+2
- 0915:AD D0 09 342 lda ThisBlock ; reset last position in dir
- 0918:0A 343 asl a ; = to block # times 512
- 0919:8D E6 09 344 sta Mark+1
- 091C:2E E7 09 345 rol Mark+2
- 091F: 346 *
- 091F:20 00 BF 347 jsr MLI ; reset the file marker
- 0922:CE 348 db mliSetMark
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 8
-
- 0923:E3 09 349 dw SetMParms
- 0925: 350 *
- 0925:20 00 BF 351 jsr MLI ; now read in the block we
- 0928:CA 352 db mliRead ; were on last.
- 0929:D9 09 353 dw ReadParms
- 092B: 354 *
- 092B:CE CE 09 355 dec Depth
- 092E:60 356 rts
- 092F: 357 *
- 092F: 358 *******************************************************
- 092F: 359 *
- 092F: 092F 360 ExtendName equ *
- 092F: 361 *
- 092F: 362 * Append the name in the current directory entry
- 092F: 363 * to the name in the directory name buffer. This
- 092F: 364 * will allow us to descend another level into the
- 092F: 365 * disk hierarchy when we call ReadDir.
- 092F: 366 *
- 092F:A0 00 367 ldy #0 ; get length of string to copy
- 0931:B1 82 368 lda (entPtr),y
- 0933:29 0F 369 and #$0F
- 0935:8D 62 09 370 sta extCnt ; save the length here
- 0938:8C 63 09 371 sty srcPtr ; init src ptr to zero
- 093B: 372 *
- 093B:A0 00 373 ldy #0 ; init dest ptr to end of
- 093D:B1 80 374 lda (dirName),y ; the current directory name
- 093F:8D 64 09 375 sta destPtr
- 0942: 376 *
- 0942: 0942 377 extloop equ *
- 0942:EE 63 09 378 inc srcPtr ; bump to next char to read
- 0945:EE 64 09 379 inc destPtr ; bump to next empty location
- 0948:AC 63 09 380 ldy srcPtr ; get char of sub-dir name
- 094B:B1 82 381 lda (entPtr),y
- 094D:AC 64 09 382 ldy destPtr ; tack on to end of cur. dir.
- 0950:91 80 383 sta (dirName),y
- 0952:CE 62 09 384 dec extCnt ; done all chars?
- 0955:D0 EB 0942 385 bne extloop ; no - so do more
- 0957: 386 *
- 0957:C8 387 iny
- 0958:A9 2F 388 lda #'/' ; tack "/" on to the end
- 095A:91 80 389 sta (dirName),y
- 095C: 390 *
- 095C:98 391 tya ; fix length of filename to open
- 095D:A0 00 392 ldy #0
- 095F:91 80 393 sta (dirName),y
- 0961: 394 *
- 0961:60 395 rts
- 0962: 396 *
- 0962: 0001 397 extCnt ds 1
- 0963: 0001 398 srcPtr ds 1
- 0964: 0001 399 destPtr ds 1
- 0965: 400 *
- 0965: 401 *
- 0965: 402 *******************************************************
- 0965: 403 *
- 0965: 0965 404 ChopName equ *
- 0965: 405 *
- 0965: 406 * Scans the current directory name, and chops
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 9
-
- 0965: 407 * off characters until it gets to a /.
- 0965: 408 *
- 0965:A0 00 409 ldy #0 ; get len of current dir.
- 0967:B1 80 410 lda (dirName),y
- 0969:A8 411 tay
- 096A: 096A 412 ChopLoop equ *
- 096A:88 413 dey ; bump to previous char
- 096B:B1 80 414 lda (dirName),y
- 096D:C9 2F 415 cmp #'/'
- 096F:D0 F9 096A 416 bne ChopLoop
- 0971:98 417 tya
- 0972:A0 00 418 ldy #0
- 0974:91 80 419 sta (dirName),y
- 0976:60 420 rts
- 0977: 421 *
- 0977: 422 *******************************************************
- 0977: 423 *
- 0977: 0977 424 GetNext equ *
- 0977: 425 *
- 0977: 426 * This routine is responsible for making a pointer
- 0977: 427 * to the next entry in the directory. If there are
- 0977: 428 * still entries to be processed in this block, then
- 0977: 429 * we simply bump the pointer by the size of the
- 0977: 430 * directory entry. If we have finished with this
- 0977: 431 * block, then we read in the next block, point to
- 0977: 432 * the first entry, and increment our block counter.
- 0977: 433 *
- 0977:CE CF 09 434 dec ThisBEntry ; dec count for this block
- 097A:F0 10 098C 435 beq ReadNext ; done w/this block, get next one
- 097C: 436 *
- 097C:18 437 clc ; else bump up index
- 097D:A5 82 438 lda entPtr
- 097F:6D D1 09 439 adc entryLen
- 0982:85 82 440 sta entPtr
- 0984:A5 83 441 lda entPtr+1
- 0986:69 00 442 adc #0
- 0988:85 83 443 sta entPtr+1
- 098A:18 444 clc ; say that the buffer's good
- 098B:60 445 rts
- 098C: 446 *
- 098C: 098C 447 ReadNext equ *
- 098C:20 00 BF 448 jsr MLI ; get the next block
- 098F:CA 449 db mliRead
- 0990:D9 09 450 dw ReadParms
- 0992:B0 16 09AA 451 bcs DirDone
- 0994: 452 *
- 0994:EE D0 09 453 inc ThisBlock
- 0997: 454 *
- 0997:A9 EF 455 lda #buffer+4 ; set entry pointer to beginning
- 0999:85 82 456 sta entPtr ; of first entry in block
- 099B:A9 09 457 lda #<buffer+4
- 099D:85 83 458 sta entPtr+1
- 099F: 459 *
- 099F:AD D2 09 460 lda entPerBlk ; re-init 'entries in this block'
- 09A2:8D CF 09 461 sta ThisBEntry
- 09A5:CE CF 09 462 dec ThisBEntry
- 09A8:18 463 clc ; return 'No error'
- 09A9:60 464 rts
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 10
-
- 09AA: 465 *
- 09AA: 09AA 466 DirDone equ *
- 09AA:38 467 sec ; return 'an error occurred' (error in A)
- 09AB:60 468 rts
- 09AC: 469 *
- 09AC: 470 *******************************************************
- 09AC: 471 *
- 09AC: 09AC 472 PrintEntry equ *
- 09AC: 473 *
- 09AC: 474 * Using the pointer to the current entry, this
- 09AC: 475 * routine prints the entry name. It also pays
- 09AC: 476 * attention to the recursion depth, and indents
- 09AC: 477 * by 2 spaces for every level.
- 09AC: 478 *
- 09AC:AD CE 09 479 lda Depth ; indent two blanks for each level
- 09AF:0A 480 asl a ; of directory nesting
- 09B0:AA 481 tax
- 09B1:F0 08 09BB 482 beq spcDone
- 09B3:A9 A0 483 spcloop lda #space
- 09B5:20 ED FD 484 jsr cout
- 09B8:CA 485 dex
- 09B9:D0 F8 09B3 486 bne spcloop
- 09BB: 09BB 487 spcDone equ *
- 09BB: 488 *
- 09BB:A0 00 489 ldy #0 ; get byte that has the length byte
- 09BD:B1 82 490 lda (entPtr),y
- 09BF:29 0F 491 and #$0F ; get just the length
- 09C1:AA 492 tax
- 09C2: 09C2 493 PrntLoop equ *
- 09C2:C8 494 iny ; bump to the next char.
- 09C3:B1 82 495 lda (entPtr),y ; get next char
- 09C5:09 80 496 ora #$80 ; COUT likes high bit set
- 09C7:20 ED FD 497 jsr cout ; print it
- 09CA:CA 498 dex ; printed all chars?
- 09CB:D0 F5 09C2 499 bne PrntLoop ; no - keep going
- 09CD:60 500 rts
- 09CE: 501 *
- 09CE: 502 *******************************************************
- 09CE: 503 *
- 09CE: 504 * Some global variables
- 09CE: 505 *
- 09CE: 0001 506 Depth ds 1 ; amount of recursion
- 09CF: 0001 507 ThisBEntry ds 1 ; entry in this block
- 09D0: 0001 508 ThisBlock ds 1 ; block with dir
- 09D1: 0001 509 entryLen ds 1 ; length of each directory entry
- 09D2: 0001 510 entPerBlk ds 1 ; entries per block
- 09D3: 511 *
- 09D3: 512 *******************************************************
- 09D3: 513 *
- 09D3: 514 * ProDOS command parameter blocks
- 09D3: 515 *
- 09D3: 09D3 516 OpenParms equ *
- 09D3:03 517 db 3 ; number of parms
- 09D4: 0002 518 OpenName ds 2 ; pointer to filename
- 09D6:00 00 519 ioBuf dw $0000 ; I/O buffer
- 09D8: 0001 520 oRefNum ds 1 ; returned refnum
- 09D9: 521 *
- 09D9: 09D9 522 ReadParms equ *
-
- 01 CATALOG ProDOS Catalog Routine 14-OCT-89 16:20 PAGE 11
-
- 09D9:04 523 db 4 ; number of parms
- 09DA: 0001 524 rRefNum ds 1 ; refnum from Open
- 09DB:EB 09 525 dw buffer ; pointer to buffer
- 09DD:00 02 526 reqAmt dw 512 ; amount to read
- 09DF: 0002 527 retAmt ds 2 ; amount actually read
- 09E1: 528 *
- 09E1: 09E1 529 CloseParms equ *
- 09E1:01 530 db 1 ; number of parms
- 09E2: 0001 531 cRefNum ds 1 ; refnum from Open
- 09E3: 532 *
- 09E3: 09E3 533 SetMParms equ *
- 09E3:02 534 db 2 ; number of parms
- 09E4: 0001 535 sRefNum ds 1 ; refnum from Open
- 09E5: 0003 536 Mark ds 3 ; file position
- 09E8: 537 *
- 09E8: 09E8 538 GetPParms equ *
- 09E8:01 539 db 1 ; number of parms
- 09E9:EB 0B 540 dw nameBuffer ; pointer to buffer
- 09EB: 541 *
- 09EB: 0200 542 buffer ds 512 ; enough for whole block
- 0BEB: 543 *
- 0BEB: 0040 544 nameBuffer ds 64 ; space for directory name
-
- 01 SYMBOL TABLE SORTED BY SYMBOL 14-OCT-89 16:20 PAGE 12
-
- 09EB BUFFER 096A CHOPLOOP 0965 CHOPNAME 09E1 CLOSEPARMS
- FDED COUT 09E2 CREFNUM FD8E CROUT 09CE DEPTH
- 0964 DESTPTR 09AA DIRDONE 80 DIRNAME 084D DONE
- 4C ENDOFFILE 09D2 ENTPERBLK 82 ENTPTR 09D1 ENTRYLEN
- 081E EXIT 0962 EXTCNT 092F EXTENDNAME 0942 EXTLOOP
- BEF5 GETBUFR 0977 GETNEXT 09E8 GETPPARMS 0878 HITDIREND
- 09D6 IOBUF 0845 ITSADIR 0831 LOOP 09E5 MARK
- CC MLICLOSE C7 MLIGETPFX C8 MLIOPEN BF00 MLI
- CA MLIREAD CE MLISETMARK 0BEB NAMEBUFFER 0848 NEXTENTRY
- 24 OENTBLK 23 OENTLEN 0879 OPENDIR 08B2 OPENDONE
- 09D4 OPENNAME 09D3 OPENPARMS 09D8 OREFNUM 00 OTYPE
- FDDA PRBYTE 09AC PRINTENTRY 09C2 PRNTLOOP 0829 READDIR1
- 081F READDIR 098C READNEXT 09D9 READPARMS 08C9 RECURSDIR
- 08F7 REOPENED ?09DD REQAMT ?09DF RETAMT 09DA RREFNUM
- 09E3 SETMPARMS A0 SPACE 09BB SPCDONE 09B3 SPCLOOP
- 0963 SRCPTR 09E4 SREFNUM ?0800 START 09CF THISBENTRY
- 09D0 THISBLOCK 08BA VISITDIR 08B3 VISITFILE
- ** SUCCESSFUL ASSEMBLY := NO ERRORS
- ** ASSEMBLER CREATED ON 15-JAN-84 21:28
- ** TOTAL LINES ASSEMBLED 544
- ** FREE SPACE PAGE COUNT 81
-
-
- Further Reference
- _____________________________________________________________________________
- o ProDOS 8 Technical Reference Manual
- o AppleShare Programmer's Guide to the Apple IIGS
-